Repository navigation
fix(libkernel): fail dlopen of an unrelinked module without the Windows Bad Image dialog - #9832
Conversation
MarcZX10
left a comment
There was a problem hiding this comment.
I reviewed head cc888176de25999eb68d6fc01d0cc641774b58da. python3 tools/check_conventions.py --base upstream/main and git diff --check upstream/main...refs/review/9832 pass. I also ran GCC 12.2 C++20 syntax-only compilation of the changed DynamicLoader.cpp and GuestDynamicLoader.cpp translation units; both compile successfully on Linux.
I did not run the CTest binary or the Windows modal-dialog reproduction here. The PR description reports the focused Windows test, repeated runs, and title reproduction; the PR's hosted Linux/Windows build jobs are skipped. The current main is two commits ahead of this head; a merge-tree check is clean. Please update to current main before merge and ensure the Windows focused test runs on the final head. I found no blocking issue in the reviewed diff.
|
Independent Windows run, as data only. Machine: Windows 11 Enterprise 10.0.22621, Ryzen 9 5950X, WinLibs GCC 15.2.0 UCRT r7, Release, AI-assisted (Claude Code). |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
cc88817 to
50a14b1
Compare
|
Rebased onto
|
cc88817 to
50a14b1
Compare
|
Follow-up on the refreshed head |
|
Thanks for rebasing and reporting the 20-repeat Windows |
…ws Bad Image dialog On Windows, dlopen passed a module that was never relinked to LoadLibraryExW, which raised the modal Bad Image hard-error dialog and blocked the calling thread until someone answered it. The load now runs with SEM_FAILCRITICALERRORS set for that thread only, so it fails at once with the same result as before. Every failed load is reported once per file on stderr with a [module] prefix; a file that exists with no relinked .guest.prx names the relinker's --module-dir option.
4894d1c to
dc84bec
Compare
|
The previous push (4894d1c) never reached this PR, which still showed 50a14b1, during today's GitHub incident with pull requests. Rebased again, onto
On 4894d1c, which is the same diff on
The Tested section of the description names this head. On the overlaps with the loader work, #9415 (fallback paths) and #8658/#6586 (macOS and Linux POSIX branch), this PR depends on none of them; each pair only conflicts on lines. I asked about the order in #9415. AI-assisted: yes |
50a14b1 to
4894d1c
Compare
What
On Windows,
dlopenpasses a module that was never relinked (a PS5 ELF or SELF that a title loads withsceKernelLoadStartModule) toLoadLibraryExW. Windows then raises its modal Bad Image hard-error dialog (0xC000012F), and the calling thread blocks until someone answers it. After that, the load fails with error 193 andsceKernelLoadStartModulereturnsSCE_KERNEL_ERROR_ENOENT, with nothing in the log.Yakuza 0 Director's Cut (PPSA31327) hits this whenever these modules are not relinked:
/app0/data/crm/ps5/crm_module_ps5.prx(the SEGA account module);/app0/data/module/ps5/yakuza_minigame_ps5_retail.prx.Unattended runs stall on the dialog.
LoadWithoutErrorDialogsetsSEM_FAILCRITICALERRORSon the calling thread for theLoadLibraryExWcall only, keeps the loader's error code, and restores the previous thread mode.PatchedLibraries.cppuses the same flag for its whole process. The module's initialization (InitializeDeferredModule) runs after the mode is restored.ENOENTand continues, as it did after someone answered the dialog.[module]prefix. This applies on Windows and on the other hosts.<name>.guest.prxgets:dlopen: <path> was not relinked: no <name>.guest.prx was found (Windows loader error 193); relink its directory with the relinker's --module-dir <dir> option.dlopen: cannot load <path> (<reason>).USAGE.mdmentions the message beside its existing note on error 193.Overlaps:
dlopen(fallback paths). Whichever PR merges second swaps itsLoadLibraryExWcalls forLoadWithoutErrorDialogand routes its final failure throughLoadFailure.__APPLE__blocks between the POSIX lines changed here, and feat(aot): consolidate native ARM64 compiler, runtime and consumers #5021 touches the CMake lines near the newTIMEOUT. These are line-level conflicts only.Tested
Windows 11 Pro 26200, WinLibs GCC 15.2.0, Release,
BUILD_TESTING=ON, on head dc84bec (maina6646f8).guest_dynamic_loadergains a check. dlopen of an existing 4-byte ELF stub that has no.guest.prxis called twice:SEM_NOGPFAULTERRORBOX.Each call must return null, with a dlerror that names the file and
--module-dir, and the thread mode must be unchanged afterwards. The missing-module dlerror must not mention--module-dir.main'sDynamicLoader.cpp, the test shows the Bad Image dialog and fails on the test's newTIMEOUT(30 s, the CI limit).was not relinkedline once for the two calls, and passes--repeat until-fail:20.Other tests that pass:
guest_dynamic_loader_variant_names,guest_deferred_module_{reload,pinned,parallel,reentrant},guest_module_info,guest_module_{dir,directories,args,identity,fini}andpatched_libraries.PPSA31327 01.015.000, relinked with only
--module-dir data/module/ps5, launched with the default error mode, from boot to gameplay:libkernelfrommain80565c5, the Bad Image dialog forcrm_module_ps5.prxappears 6 s after start.main0def01b (head 4894d1c, the same diff), no dialog appears, and stderr has one[module] dlopen: ...crm_module_ps5.prx was not relinked ...line. The title reaches gameplay, at about 200,000 draws per 10 s.Linux:
DynamicLoader.cppandGuestDynamicLoader.cppcompile with GCC 15.2.0 (-Wall -Wextra, no warnings) in WSL Ubuntu. The test was not run there. On Linux and macOS the change is only the reporting:LoadFailureinstead ofError(::dlerror()).Not tested: macOS.
tools/check_conventions.py --base origin/mainpasses.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)